#ifndef GA_EXCEPTION_H_
#define GA_EXCEPTION_H_

#include <iostream>

/** Thrown when a particular template is not supported.
 */
class Unsupported_template_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when an environment is not supported.
 */
class Unsupported_environment_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when an environment hasn't been configured yet.
 */
class Environment_not_configured_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when an element index is not valid.
 */
class Invalid_element_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when a given solution has an unusable size.
 */
class Invalid_solution_size_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when a given file cannot be found or opened.
 */
class Invalid_file_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when a given configuration is invalid.
 */
class Invalid_configuration_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when a given size is invalid.
 */
class Invalid_size_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when an environment has not been provided to an object that requires it.
 */
class No_environment_set_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when no crossover object has been provided to an object that requires it.
 */
class No_crossover_set_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when a job type is not supported.
 */
class Unsupported_job_type_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when a worker is issued a task when not idle.
 */
class Worker_not_idle_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when someone attempts to register a worker that is already registered.
 */
class Worker_already_registered_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when a worker attempts to do something with the framework when it hasn't been registered.
 */
class Worker_not_registered_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when someone attempts to create an invalid selection
 */
class Unsupported_selection_exception : public std::exception
{
    virtual const char* what() const throw();
};

/** Thrown when someone attempts to create an invalid selection
 */
class Unsupported_crossover_exception : public std::exception
{
    virtual const char* what() const throw();
};

/**
 * Thrown when an index provided to a function is out of bounds.
 */
class Invalid_index_exception : public std::exception
{
    virtual const char* what() const throw();
};

/**
 * Thrown when a buffer used in the system cannot contain the 
 * data to be placed in it
 */
class Buffer_undersized_exception : public std::exception
{
    virtual const char* what() const throw();
};

/**
 * Thrown when an error occurs during deserialization
 */
class Deserialization_exception : public std::exception
{
    virtual const char* what() const throw();
};

/**
 * Thrown when an error occurs during Serialization
 */
class Serialization_exception : public std::exception
{
    virtual const char* what() const throw();
};

#endif /*GA_EXCEPTION_H_*/
